<?php

class __admin_system_modules extends Module {
	
	public function __construct() {
		parent::__construct('system');
	}
	
	public function modules() {
		$this->setPageTitle(lang('admin_header_modules','system'));
		
		$oTypeModule = TypesController::getInstance()->getTypeByName('explay_module');

		$sel = new Selection;
		$sel->addType($oTypeModule);
		
		$aObjects = ObjectsController::getInstance()->getObjectsList($sel->getList());
		
		$response = new ModuleResponse;
		$response->setTemplate('system/modules/list');
		
		if (getRequest('created','bool')) {
			$response->addObject(new SystemMessage(lang('admin_module_created','system')));
		}
		if (getRequest('saved','bool')) {
			$response->addObject(new SystemMessage(lang('admin_module_saved','system')));
		}
		if (getRequest('deleted','bool')) {
			$response->addObject(new SystemMessage(lang('admin_module_deleted','system')));
		}
		
		foreach ($aObjects as $object) {
			$response->addObject($object);
		}
		
		return $response;
	}
	
	public function module_export() {
		$oTypeModule = TypesController::getInstance()->getTypeByName('explay_module');
		
		$id = getRequest('param0','int');
		
		if (!$oModule = ObjectsController::getInstance()->getObject($oTypeModule, $id)) {
			throw new NotFound;
		}
		
		if (getRequest('do','bool')) {
			$this->buildModule($oModule);
		}
		
		$response = new ModuleResponse;
		$response->setTemplate('system/modules/export');
		$response->setAttribute('module-id', $id);
		$response->addObject($oModule);

		return $response;
	}
	
	public function module_ajax_files() {
		$this->setResponseFormat('xml');
		
		$response = new ModuleResponse;
		$response->addObject(FilesController::getFolder(DOC_ROOT . '/' . trim(getRequest('folder'), '/')));
		
		return $response;
	}
	
	public function delete_module() {
		$oTypeModule = TypesController::getInstance()->getTypeByName('explay_module');
		
		$id = getRequest('param0','int');
		
		if (!$oModule = ObjectsController::getInstance()->getObject($oTypeModule, $id)) {
			throw new NotFound;
		}
		
		if (getRequest('do','bool')) {
			$oModule->delete();
			
			if (isset($_POST['files']) && is_array($_POST['files'])) {
				foreach ($_POST['files'] as $file) {
					$oFile = new File($file);
					$oFile->delete();
				}
			}
			
			redirect(HTTP_HOST . '/admin/system/modules?deleted');
		}
		
		$response = new ModuleResponse;
		$response->setTemplate('system/modules/delete');
		$response->setAttribute('module-id', $id);
		$response->addObject($oModule);

		return $response;
	}
	
	public function create_module() {
		$this->setPageTitle(lang('admin_header_create_module','system'));
		return $this->form();
	}
	
	public function edit_module() {
		$this->setPageTitle(lang('admin_header_edit_module','system'));
		return $this->form(getRequest('param0','int'));
	}
	
	public function upload_module() {
		if (!isset($_FILES['file']) || $_FILES['file']['name'] == '') {
			$lang = lang('errro_admin_module_install_file_not_uploaded','system');
			$content = <<<HTML
<script type="text/javascript">parent.moduleInstallError('{$lang}');</script>
HTML;
			$this->flush($content, 'text/html');
		}
		
		$path = ENGINE_ROOT . '/temp/install_module.zip';
		
		if (!FilesController::uploadFile($_FILES['file'], $path, true)) {
			$lang = lang('errro_admin_module_install_file_not_uploaded','system');
			$content = <<<HTML
<script type="text/javascript">parent.moduleInstallError('{$lang}');</script>
HTML;
			$this->flush($content, 'text/html');
		}
		
		include ENGINE_ROOT . '/libs/pclzip.lib.php';
		
		$zip = new PclZip($path);
		
		// Выбираем основные настсройки
		
		$listContent = $zip->extract(PCLZIP_OPT_BY_NAME, 'moduleInfo.xml', PCLZIP_OPT_EXTRACT_AS_STRING);
		
		if (!count ($listContent)) {
			unlink($path);
			
			$lang = lang('errro_admin_module_install_info_not_found','system');
			$content = <<<HTML
<script type="text/javascript">parent.moduleInstallError('{$lang}');</script>
HTML;
			$this->flush($content, 'text/html');
		}
		
		$xml = new DOMDocument;
		if (!$xml->loadXML($listContent[0]['content'],LIBXML_NOERROR)) {
			unlink($path);
			
			$lang = lang('errro_admin_module_install_bad_info','system');
			$content = <<<HTML
<script type="text/javascript">parent.moduleInstallError('{$lang}');</script>
HTML;
			$this->flush($content, 'text/html');
		}
		
		$module = $xml->getElementsByTagName('module');
		
		if (!$module->length) {
			unlink($path);
			
			$lang = lang('errro_admin_module_install_bad_info','system');
			$content = <<<HTML
<script type="text/javascript">parent.moduleInstallError('{$lang}');</script>
HTML;
			$this->flush($content, 'text/html');
		}
		
		$module = $module->item(0);
		
		$_SESSION['module']['name'] = $module->getElementsByTagName('name')->length ? $module->getElementsByTagName('name')->item(0)->nodeValue : '';
		$_SESSION['module']['title'] = $module->getElementsByTagName('title')->length ? $module->getElementsByTagName('title')->item(0)->nodeValue : '';
		$_SESSION['module']['version'] = $module->getElementsByTagName('version')->length ? $module->getElementsByTagName('version')->item(0)->nodeValue : '';
		$_SESSION['module']['description'] = $module->getElementsByTagName('description')->length ? $module->getElementsByTagName('description')->item(0)->nodeValue : '';
		$_SESSION['module']['author_name'] = $module->getElementsByTagName('authorName')->length ? $module->getElementsByTagName('authorName')->item(0)->nodeValue : '';
		$_SESSION['module']['author_page'] = $module->getElementsByTagName('authorPage')->length ? $module->getElementsByTagName('authorPage')->item(0)->nodeValue : '';
		$_SESSION['module']['module_page'] = $module->getElementsByTagName('modulePage')->length ? $module->getElementsByTagName('modulePage')->item(0)->nodeValue : '';
		$_SESSION['module']['avatar'] = $module->getElementsByTagName('avatar')->length ? $module->getElementsByTagName('avatar')->item(0)->nodeValue : '';
		
		// Проверки
		
		if ($_SESSION['module']['name'] == '' || $_SESSION['module']['title'] == '' || $_SESSION['module']['version'] == '') {
			unlink($path);
			
			$lang = lang('errro_admin_module_install_bad_info','system');
			$content = <<<HTML
<script type="text/javascript">parent.moduleInstallError('{$lang}');</script>
HTML;
			$this->flush($content, 'text/html');
		}
		
		if (in_array($_SESSION['module']['name'], scandir(ENGINE_ROOT . '/modules'))) {
			unlink($path);
			
			$lang = lang('errro_admin_module_install_exists','system');
			$content = <<<HTML
<script type="text/javascript">parent.moduleInstallError('{$lang}');</script>
HTML;
			$this->flush($content, 'text/html');
		}
		
		// Проверка на существование модуля в базе
		
		$testSel = new Selection;
		$testSel->addType(TypesController::getInstance()->getTypeByName('explay_module'));
		$testSel->addFilter('name', $_SESSION['module']['name']);
		
		if ($testSel->getTotalCount()) {
			unlink($path);
			
			$lang = lang('errro_admin_module_install_exists','system');
			$content = <<<HTML
<script type="text/javascript">parent.moduleInstallError('{$lang}');</script>
HTML;
			$this->flush($content, 'text/html');
		}
		
		
		// Все ОК
		
		$content = <<<HTML
<script type="text/javascript">
parent.moduleContinueInstall({
	name : "{$_SESSION['module']['name']}",
	title : "{$_SESSION['module']['title']}",
	version : "{$_SESSION['module']['version']}",
	description : "{$_SESSION['module']['description']}",
	authorName : "{$_SESSION['module']['author_name']}",
	authorPage : "{$_SESSION['module']['author_page']}",
	modulePage : "{$_SESSION['module']['module_page']}",
	avatar : "{$_SESSION['module']['avatar']}"
});
</script>
HTML;
		
		$this->flush($content, 'text/html');
	}
	
	public function continue_module_install() {
		if (getRequest('break','bool')) {
			$file = ENGINE_ROOT . '/temp/install_module.zip';
			
			if (file_exists($file)) {
				unlink($file);
			}
			
			$content = <<<HTML
<script type="text/javascript">parent.closeModuleInstallDialog();</script>
HTML;
			$this->flush($content, 'text/html');
		}
		if (getRequest('continue','bool')) {
			$file = ENGINE_ROOT . '/temp/install_module.zip';
			
			if (!file_exists($file)) {
				$lang = lang('errro_admin_module_install_zip_deleted','system');
				$content = <<<HTML
<script type="text/javascript">parent.moduleInstallError('{$lang}');</script>
HTML;
				$this->flush($content, 'text/html');
			}
			
			if (!isset($_SESSION['module'])) {
				unlink($file);
				
				$lang = lang('errro_admin_module_install_session','system');
				$content = <<<HTML
<script type="text/javascript">parent.moduleInstallError('{$lang}');</script>
HTML;
				$this->flush($content, 'text/html');
			}
			
			include ENGINE_ROOT . '/libs/pclzip.lib.php';
			
			$zip = new PclZip($file);
			
			if (!$zip->extract()) {
				unlink($file);
				
				$zipError = $zip->errorInfo(true);
				
				$content = <<<HTML
<script type="text/javascript">parent.moduleInstallError('Zip error: {$zipError}');</script>
HTML;
				$this->flush($content, 'text/html');
			}
			
			if (file_exists(DOC_ROOT . '/moduleInfo.xml')) {
				unlink(DOC_ROOT . '/moduleInfo.xml');
			}
			
			$oTypeModule = TypesController::getInstance()->getTypeByName('explay_module');
			
			$object = new Object($oTypeModule);
			$object->setValues(array(
				'name' => $_SESSION['module']['name'],
				'title' => $_SESSION['module']['title'],
				'description' => $_SESSION['module']['description'],
				'version' => $_SESSION['module']['version'],
				'author_name' => $_SESSION['module']['author_name'],
				'author_uri' => $_SESSION['module']['author_page'],
				'page_uri' => $_SESSION['module']['module_page'],
				'avatar' => $_SESSION['module']['avatar']
			));
			$object->createNew();
			
			$content = <<<HTML
<script type="text/javascript">parent.moduleInstallExit();</script>
HTML;
			$this->flush($content, 'text/html');
		}
		
		$this->flush('');
	}
	
	private function buildModule(Object $oModule) {
		include ENGINE_ROOT . '/libs/pclzip.lib.php';
		
		$name = $oModule->getValue('name');
		
		$zipFile = DOC_ROOT . '/module_' . $name . '.zip';
		$zip = new PclZip($zipFile);
		
		$infoFile = ENGINE_ROOT . '/temp/moduleInfo.xml';
		file_put_contents($infoFile, $this->getModuleInfoXML($oModule)->saveXML());
		
		$zip->create($infoFile, PCLZIP_OPT_REMOVE_PATH, ENGINE_ROOT . '/temp');
		
		if (isset($_POST['files']) && is_array($_POST['files'])) {
			foreach($_POST['files'] as $file) {
				$zip->add(DOC_ROOT . '/' . trim($file, '/'), PCLZIP_OPT_REMOVE_PATH, DOC_ROOT);
			}
		}
		
		redirect(HTTP_HOST . '/module_' . $name . '.zip');
	}
	
	private function getModuleInfoXML(Object $oModule) {
		$xml = new DOMDocument('1.0', 'utf-8');
		
		$moduleNode = $xml->createElement('module');
		
		$moduleNode->appendChild($xml->createElement('name', $oModule->getValue('name')));
		$moduleNode->appendChild($xml->createElement('title', $oModule->getValue('title')));
		$moduleNode->appendChild($xml->createElement('version', $oModule->getValue('version')));
		$moduleNode->appendChild($xml->createElement('description', $oModule->getValue('description')));
		$moduleNode->appendChild($xml->createElement('authorName', $oModule->getValue('author_name')));
		$moduleNode->appendChild($xml->createElement('authorPage', $oModule->getValue('author_uri')));
		$moduleNode->appendChild($xml->createElement('modulePage', $oModule->getValue('page_uri')));
		$moduleNode->appendChild($xml->createElement('requiredModules', implode(',', $oModule->getValue('required_modules'))));
		
		$xml->appendChild($moduleNode);
		
		return $xml;
	}
	
	private function form($id = 'new') {
		$oTypeModule = TypesController::getInstance()->getTypeByName('explay_module');
		
		$form = new Form ($oTypeModule, $id);
		$form->buildFromType ();
		
		$aValues = array ();
		$aErrors = array ();
		
		if ($id != 'new') {
			if (!$object = ObjectsController::getInstance()->getObject ($oTypeModule, $id)) {
				throw new NotFound;
			}
			
			$aValues = $object->getValues ();
		}
		
		if ((getRequest ('param1') == 'save' && $id != 'new') || (getRequest ('param0') == 'save' && $id == 'new')) {
			$aValues = $this->getRequestData ($id, $oTypeModule);
			
			if ($id == 'new') {
				$object = new Object ($oTypeModule);
				$object->setValues ($aValues);
				$object->setValue('my', 1);
			} else {
				$object->setValues ($aValues);
			}
				
			$aErrors = $this->getValidateErrors($object);
			
			if (!isset($aErrors['name']) && $id == 'new') {
				if (in_array($object->getValue('name'), scandir(ENGINE_ROOT . '/modules'))) {
					$aErrors['name'] = lang('error_admin_module_name_exists','system');
				}
			}
			
			if (!isset($aErrors['name'])) {
				$sel = new Selection;
				$sel->addType($oTypeModule);
				$sel->addFilter('name', $object->getValue('name'));
				if ($id != 'new') {
					$sel->addFilter('id', $id, '!=');
				}
				
				if ($sel->getTotalCount()) {
					$aErrors['name'] = lang('error_admin_module_name_exists','system');
				}
			}
			
			if (!count ($aErrors)) {
				if ($id == 'new') {
					$object->createNew ();
					
					redirect (HTTP_HOST . '/admin/system/modules?created');
				} else {
					$object->save ();
					
					redirect (HTTP_HOST . '/admin/system/modules?saved');
				}
			}
		}
		
		$form->setErrors ($aErrors);
		$form->setValues ($aValues);
		
		$response = new ModuleResponse;
		$response->setTemplate ('system/modules/form');
		$response->addObject ($form);
		
		return $response;
	}
	
}